from django.shortcuts import render
from django.utils import timezone
from django.views import View
from django import http
from django.core.paginator import Paginator,EmptyPage

from goods.models import GoodsCategory,SKU,GoodsVisitModel
from contents.utils import get_categories
from .utils import get_breadcrumb
from meiduo_mall.utils.response_code import RETCODE
from orders.models import OrderGoods,OrderInfo
from users.models import User

class ListGoodsView(View):
    """商品分类"""
    def get(self, request, category_id, page_num):
        # 前端请求：/list/category_id/page_num/?sort=xx/
        # 判断category_id是否存在
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseForbidden('category_id不存在')
        # 获取数据sort
        sort = request.GET.get('sort','default')
        if sort == 'price':
            sort_filed = '-price'
            # 按价格倒序查到所有的商品
            # sku_qs = category.sku_set.filter(is_launched=True).order_by('-price')
        elif sort == 'hot':
            sort_filed = '-sales'
            # 按人气倒叙查到所有的商品
            # sku_qs = category.sku_set.filter(is_launched=True).order_by('-sales')
        else:
            sort = 'default'
            sort_filed = 'create_time'
            # sku_qs = category.sku_set.filter(is_launched=True).order_by('create_time')
        # 按排序方式查到所有的商品
        sku_qs = category.sku_set.filter(is_launched=True).order_by(sort_filed)
        # 创建分页器对象
        paginator = Paginator(sku_qs,5)
        # .page(页数）表示分页后根据第几页请求要展示的数据
        try:
            page_skus = paginator.page(page_num) # (n-1)*5:n*5-1
        except EmptyPage:
            return http.HttpResponseForbidden('页数不存在')
        total_page = paginator.num_pages    # 总页数
        context = {
            'categories':get_categories(),
            'breadcrumb':get_breadcrumb(category),
            'sort':sort,
            'page_num': page_num,
            'total_page':total_page,
            'page_skus': page_skus,
            'category':category,
        }

        return render(request, 'list.html', context)


class HotGoodsView(View):
    """热销商品"""
    def get(self, request, category_id):
        # 请求地址 '/hot/' + this.category_id + '/';
        # 判断category_id是否存在
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseForbidden('category_id不存在')
        # 查询销量排行前两位的商品（查询集）
        sku_qs = category.sku_set.filter(is_launched=True).order_by('-sales')[0:2]
        # 准备一个空列表装商品字典响应给前端 hot_skus:[]
        sku_list = []
        # 遍历查询集包装成一个字典
        for sku in sku_qs:
            sku = {
                "id":sku.id,
                'price':sku.price,
                'name':sku.name,
                'default_image_url':sku.default_image.url
            }
            sku_list.append(sku)
        # 响应
        return http.JsonResponse({'code':RETCODE.OK, 'errmsg':'OK', 'hot_skus':sku_list})


class DetailGoodsView(View):
    """商品详情"""
    def get(self, request, sku_id):
        # 判断sku_id是否存在
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return http.HttpResponseForbidden('sku_id不存在')
        category = sku.category  # 获取当前sku所对应的三级分类

        # 查询当前sku所对应的spu
        spu = sku.spu

        """1.准备当前商品的规格选项列表 [8, 11]"""
        # 获取出当前正显示的sku商品的规格选项id列表
        current_sku_spec_qs = sku.specs.order_by('spec_id')
        current_sku_option_ids = []  # [8, 11]
        for current_sku_spec in current_sku_spec_qs:
            current_sku_option_ids.append(current_sku_spec.option_id)

        """2.构造规格选择仓库
        {(8, 11): 3, (8, 12): 4, (9, 11): 5, (9, 12): 6, (10, 11): 7, (10, 12): 8}
        """
        # 构造规格选择仓库
        temp_sku_qs = spu.sku_set.all()  # 获取当前spu下的所有sku
        # 选项仓库大字典
        spec_sku_map = {}  # {(8, 11): 3, (8, 12): 4, (9, 11): 5, (9, 12): 6, (10, 11): 7, (10, 12): 8}
        for temp_sku in temp_sku_qs:
            # 查询每一个sku的规格数据
            temp_spec_qs = temp_sku.specs.order_by('spec_id')
            temp_sku_option_ids = []  # 用来包装每个sku的选项值
            for temp_spec in temp_spec_qs:
                temp_sku_option_ids.append(temp_spec.option_id)
            spec_sku_map[tuple(temp_sku_option_ids)] = temp_sku.id

        """3.组合 并找到sku_id 绑定"""
        spu_spec_qs = spu.specs.order_by('id')  # 获取当前spu中的所有规格

        for index, spec in enumerate(spu_spec_qs):  # 遍历当前所有的规格
            spec_option_qs = spec.options.all()  # 获取当前规格中的所有选项
            temp_option_ids = current_sku_option_ids[:]  # 复制一个新的当前显示商品的规格选项列表
            for option in spec_option_qs:  # 遍历当前规格下的所有选项
                temp_option_ids[index] = option.id  # [8, 12]
                option.sku_id = spec_sku_map.get(tuple(temp_option_ids))  # 给每个选项对象绑定下他sku_id属性

            spec.spec_options = spec_option_qs  # 把规格下的所有选项绑定到规格对象的spec_options属性上

        context = {
            'categories': get_categories(),  # 商品分类
            'breadcrumb': get_breadcrumb(category),  # 面包屑导航
            'sku': sku,  # 当前要显示的sku模型对象
            'category': category,  # 当前的显示sku所属的三级类别
            'spu': spu,  # sku所属的spu
            'spec_qs': spu_spec_qs,  # 当前商品的所有规格数据
        }
        return render(request, 'detail.html', context)


class VisitGoodsView(View):
    """记录商品访问量"""
    def post(self, request, category_id):
        # 该请求在访问商品详情时调用了
        # 请求地址'/visit/' + this.category_id + '/';
        # 判断category_id是否存在
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseForbidden('category_id不存在')
        # 获取当前时间日期对象
        now_date = timezone.now()
        try:
            # 查询判断是否已存在
            good_visit = GoodsVisitModel.objects.get(category=category,date=now_date)
        except GoodsVisitModel.DoesNotExist:
            # 不存在创建新的数据
            good_visit = GoodsVisitModel.objects.create(category=category)
        # 无论是否存在访问量都+1
        good_visit.count += 1
        good_visit.save()
        return http.JsonResponse({'code':RETCODE.OK,'errmsg':'OK'})


class GetGoodsCommentView(View):
    """商品详情评论界面"""
    def get(self,request,sku_id):
        try:
            sku = SKU.objects.get(id=sku_id)
        except:
            return http.HttpResponseForbidden('sku_id有误')
        order_goods_qs = OrderGoods.objects.filter(sku_id=sku.id,is_commented=True)
        comment_list = []
        for order_goods in order_goods_qs:
            user = order_goods.order.user
            comment_list.append({
                'comment':order_goods.comment,
                'username':user.username
            })

        return http.JsonResponse({'code':RETCODE.OK,'errmsg':'OK','comment_list':comment_list})

